#ifndef FUNCTION_HPP_
#define FUNCTION_HPP_

#include <Eigen/Core>
#include <Eigen/src/Core/Matrix.h>
#include <cmath>

/*定义函数基类，需要定义域维度，提供求值和求梯度的功能*/
template <int dim> class Function {
public:
  Function() {}
  virtual ~Function() {}
  virtual double operator()(const Eigen::Vector<double, dim> &point) const = 0;
  virtual Eigen::Vector<double, dim>
  gradient(const Eigen::Vector<double, dim> &point) const {
    Eigen::Vector<double, dim> grad;
    grad.setZero();
    for (int i = 0; i < dim; i++) {
      Eigen::Vector<double, dim> shift;
      shift.setZero();
      double delta = 1e-5;
      shift(i) = delta;
      grad(i) = ((*this)(point + shift) - (*this)(point)) / delta;
    }
    return grad;
  }
};

#endif